#pragma once
#include <iostream>
#include <sstream>
#include <string>
#include <memory>
#include <jsoncpp/json/json.h>
#include <stdio.h>
#include <time.h>
#include<random>
#include<atomic>
#include<iomanip>

//日志宏的编写
#define LDBG 0
#define LIFO 1
#define LERR 2
#define LDEFAULT LDBG
#define LOG(level, format, ...)                                                              \
    {                                                                                        \
        if (level >= LDEFAULT)                                                               \
        {                                                                                    \
            time_t t = time(NULL);                                                           \
            struct tm *tl = localtime(&t);                                                   \
            char time_tmp[32] = {0};                                                         \
            strftime(time_tmp, 31, "%m-%d %T", tl);                                          \
            printf("[%s] [%s:%d]" format "\n", time_tmp, __FILE__, __LINE__, ##__VA_ARGS__); \
        }                                                                                    \
    }
#define DLOG(format, ...) LOG(LDBG, format, ##__VA_ARGS__)
#define ILOG(format, ...) LOG(LIFO, format, ##__VA_ARGS__)
#define ELOG(format, ...) LOG(LERR, format, ##__VA_ARGS__)
//Json的序列化和反序列化
class JsonUnit
{
public:
    static bool serialize(Json::Value &val, std::string &body)
    {
        std::stringstream ss;
        Json::StreamWriterBuilder swb;
        std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
        sw->write(val, &ss);
        body = ss.str();
        return true;
    }
    static bool unserialize(const std::string &body, Json::Value &val)
    {
        Json::CharReaderBuilder crb;
        std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
        std::string errs;
        bool res = cr->parse(body.c_str(), body.c_str() + body.size(), &val, &errs);
        if (!res)
        {
            ELOG("unserialize fail::%s", errs.c_str());
        }
        return true;
    }
};
//uuid
class UUID
{
    public:
    static std::string uuid()
    {
        std::stringstream ss;
        std::random_device rd;
        std::mt19937 generator(rd());
        std::uniform_int_distribution<int> distribution(0,255);
        for(int i=0;i<8;i++)
        {
            if(i==4||i==6) ss<<"-";
            ss<<std::setw(2)<<std::setfill('0')<<std::hex<<distribution(generator);
        }
        ss<<"-";
        static std::atomic<size_t> seq(1);
        size_t cur=seq.fetch_add(1);
        for(int i=7;i>=0;i--)
        {
            if(i==5)ss<<"-";
            ss<<std::setw(2)<<std::setfill('0')<<std::hex<<((cur>>(i*8))&0xFF);
        }
        return ss.str();
    }
};
